import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as tcp


# from numpy.core.defchararray import upper


def connection(modbus_ip, port_id):
    server = tcp.TcpMaster(modbus_ip, port_id)
    server.set_timeout(5.0)
    return server


def change_modbus_value(modbus_ip, port_id, starting_address, data_type, point_value, reading_function_code="0X03",
                        is_thirdparty_equipment="0"):
    port_id = int(port_id)
    starting_address = int(starting_address) - 1
    reading_function_code = reading_function_code.upper()
    data_type = data_type.upper()
    data_format = ""
    print(point_value)
    if data_type == "FLOAT32":
        data_format = ">f"
        point_value = [float(point_value)]
    elif data_type == "DOUBLE":
        data_format = ">d"
        point_value = [float(point_value)]
    elif data_type in ("INT8", "INT16", "UINT8", "UINT16", "MOD10000", "BOOL"):
        data_format = ">H"
        if '.' in point_value:
            point_value = (str(point_value).split('.')[0])
        point_value = [int(point_value)]
    elif data_type in ("INT32", "UINT32"):
        data_format = ">i"
        point_value = [int(point_value)]
    elif data_type in ("INT64", "UINT64"):
        data_format = ">ll"
        point_value = [0, int(point_value)]
    else:
        print("Error")

    server = connection(modbus_ip, port_id)
    if reading_function_code == "0X03":
        reading_function_code = cst.WRITE_MULTIPLE_REGISTERS
    elif reading_function_code == "0X01":
        reading_function_code = cst.WRITE_SINGLE_COIL
        data_format = ">i"
    else:
        print("Error")
    # if function_code or data_format is wrong, the server execute will fail
    try:
        server.execute(slave=1, function_code=reading_function_code, starting_address=starting_address,
                       output_value=point_value, data_format=data_format)
    except Exception as e:
        print("Exception:", e, "Please check parameters: data_format and reading_function_code")
    server.close()
